﻿using DG.Tweening;
using Spine;
using Spine.Unity;
using UnityEngine;
using FutureCore;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace DesignerProject
{
    public class ArmsEditor : MonoBehaviour
    {
        public enum CampType
        {
            [EnumLabel("进攻兵种")]
            Atk,
            [EnumLabel("防守兵种")]
            Def,
        }

        [Header("[兵种表]")]
        [EnumLabel("攻守阵营")]
        public CampType campType = CampType.Atk;

        [RenameField("兵种Id")]
        public int armsId = 21001;

        [RenameField("兵种等级")]
        public int lv = 1;

        [RenameField("兵种名字", false)]
        public string armsName;

        [Header("[模型表]")]
        [SetRange("高度", 0, 5)]
        public float height;

        [SetRange("缩放", 0.1f, 5f)]
        public float scale;

        [Header("[属性表]")]
        [SetRange("移速", 0f, 5f)]
        public float moveSpeed;

        [SetRange("范围", 0f, 15f)]
        public float range;

        [Header("[对象]")]
        [RenameField("初始位置")]
        public Vector2 initPos;

        [Space(10)]
        [Header("Func - [控制]")]
        [TestButtonCall("创建兵种")]
        [SerializeField]
        private bool CreateArms_TestBtn;

        [Space(3)]
        [TestButtonCall("重置兵种")]
        [SerializeField]
        private bool ResetArms_TestBtn;

        [Space(3)]
        [TestButtonCall("删除兵种")]
        [SerializeField]
        private bool DeleteArms_TestBtn;

        [Space(3)]
        [TestButtonCall("控制视图显示")]
        [SerializeField]
        private bool ControlViewShow_TestBtn;

        [Header("Func - [移动调试]")]
        [TestButtonCall("开始移动")]
        [SerializeField]
        private bool StartMove_TestBtn;

        [Header("Func - [骨骼调试]")]
        [Space(3)]
        [TestButtonCall("切换到攻击帧")]
        [SerializeField]
        private bool SwitchAtkFrame_TestBtn;

        [Space(3)]
        [TestButtonCall("加载骨骼")]
        [SerializeField]
        private bool LoadBones_TestBtn;

        [Space(3)]
        [TestButtonCall("加载空骨骼")]
        [SerializeField]
        private bool LoadEmptyBones_TestBtn;

        [Space(3)]
        [TestButtonCall("保存骨骼")]
        [SerializeField]
        private bool SaveBones_TestBtn;

        private bool isCreate;
        private int objModelId;
        private int attributeId;
        private GameObject actorGo;
        private GameObject rightActorGo;
        private SkeletonAnimation animCom;
        private GameObject hpGo;
        private GameObject rangeGo;
        private GameObject bonesGo;
        private ObjModelVO objModelVO;
        private Tweener normalMoveTweener;

        private void CreateArms()
        {
            isCreate = true;

            string armsName;
            if (campType == CampType.Atk)
            {
                AtkArmsVO armsVO = AtkArmsVOModel.Instance.GetVO(armsId);
                objModelId = armsVO.modelId;
                attributeId = armsVO.attributeId;
                armsName = armsVO.name;
            }
            else
            {
                DefArmsVO armsVO = DefArmsVOModel.Instance.GetVO(armsId);
                objModelId = armsVO.modelId;
                attributeId = armsVO.attributeId;
                armsName = armsVO.name;
            }
            objModelVO = ObjModelVOModel.Instance.GetVO(objModelId);
            AttributeVO attVO = AttributeVOModel.Instance.GetVOByAttributeIdAndLv(attributeId, lv);

            actorGo = Instantiate(Resources.Load<GameObject>("Skeleton/" + objModelId));
            rightActorGo = actorGo.transform.GetChild(0).gameObject;
            animCom = rightActorGo.GetComponent<SkeletonAnimation>();
            SpineHelper.SetSortingOrder(animCom, FightRenderSortConst.Actor_Top);
            initPos = new Vector2(3f, -15.98f);
            actorGo.transform.position = initPos;
            hpGo = Instantiate(Resources.Load<GameObject>("Prefab/Fight/TopHeadUI"));
            hpGo.SetParent(actorGo.transform);
            CreateRange();

            ShowModelValue(objModelVO);
            ShowArmsValue(armsName);
            ShowAttributeValue(attVO);
            SetArms();
        }

        private void CreateRange()
        {
            string path = "Prefab/Fight/Range";
            rangeGo = Instantiate(Resources.Load<GameObject>(path));
            rangeGo.SetParent(actorGo);
        }

        private void SetRange(float range)
        {
            range *= 2;
            rangeGo.transform.localScale = new Vector3(range, range, 0);
            Renderer render = rangeGo.GetComponent<Renderer>();
            render.sortingOrder = FightRenderSortConst.Actor_Top - 1;
        }

        private void ShowModelValue(ObjModelVO modelVo)
        {
            armsName = modelVo.name;
            height = modelVo.height;
            scale = modelVo.scale;
        }

        private void ShowArmsValue(string armsName)
        {
            this.armsName = armsName;
        }

        private void ShowAttributeValue(AttributeVO attVO)
        {
            moveSpeed = attVO.moveSpeed;
            range = attVO.range;
            SetRange(range);
        }

        private void SetArms()
        {
            hpGo.transform.localPosition = new Vector3(0, height, 0);
            rightActorGo.transform.localScale = new Vector3(scale, scale, 0);
            SetRange(range);
            actorGo.transform.position = initPos;
        }

        private void ControlViewShow()
        {
            hpGo.SetActive(!hpGo.activeSelf);
            rangeGo.SetActive(!rangeGo.activeSelf);
        }

        private void StartMove()
        {
            SpineHelper.LoopPlayAnim(animCom, FightActorAnimType.Move.ToString());
            Vector2 nextWayPos = new Vector2(initPos.x + 10, initPos.y);
            float distance = Vector3.Distance(initPos, nextWayPos);
            float totalMoveTime = distance / moveSpeed;
            normalMoveTweener = actorGo.transform.DOMove(nextWayPos, totalMoveTime);
            normalMoveTweener.SetEase(Ease.Linear);
            normalMoveTweener.SetLoops(-1);
        }

        private void SwitchAtkFrame()
        {
            FightAnimFrameConfig frameCofing = objModelVO.AtkFrameConfig;
            TrackEntry te = SpineHelper.PlayAnim(animCom, FightActorAnimType.Atk.ToString());
            te.AnimationStart = frameCofing.keyFrameTime;
            te.AnimationEnd = frameCofing.keyFrameTime;
        }

        private void LoadBones()
        {
            bonesGo = Instantiate(Resources.Load<GameObject>("Designer/Bones/" + objModelId));
            bonesGo.SetParent(actorGo.transform);
        }

        private void LoadEmptyBones()
        {
            bonesGo = Instantiate(Resources.Load<GameObject>("Prefab/Fight/Bones"));
            bonesGo.SetParent(actorGo.transform);
        }

        private void SaveBones()
        {
#if UNITY_EDITOR
            PrefabUtility.CreatePrefab("Assets/_Game/Resources/Designer/Bones/" + objModelId + ".prefab", bonesGo);
#endif
        }

        private void ResetArms()
        {
            SpineHelper.LoopPlayAnim(animCom, FightActorAnimType.Idle.ToString());
            normalMoveTweener.Kill();
            actorGo.transform.position = initPos;
            Destroy(bonesGo);
        }

        public void DeleteArms()
        {
            isCreate = false;
            Destroy(actorGo);
        }

        private void Awake()
        {
            AtkArmsVOModel.Instance.Init();
            DefArmsVOModel.Instance.Init();
            ObjModelVOModel.Instance.Init();
            AttributeVOModel.Instance.Init();
        }

        private void Update()
        {
            if (isCreate)
            {
                SetArms();
            }
        }
    }
}